feat(customcurrencies): support custom currency credit purchases#4773
Conversation
📝 WalkthroughWalkthroughCustom-currency handling now uses explicit enablement in charge services, separates purchased credit currencies from fiat settlement currencies, updates invoice gathering-line construction, and expands validation and integration test coverage. ChangesCustom currency settlement handling
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant TestSuite
participant CreditPurchaseService
participant ChargeStore
participant GatheringLine
TestSuite->>CreditPurchaseService: Create custom-currency intent
CreditPurchaseService->>CreditPurchaseService: Check custom-currency enablement
CreditPurchaseService->>GatheringLine: Build fiat-priced invoice line
CreditPurchaseService->>ChargeStore: Persist charge and settlement
ChargeStore-->>TestSuite: Return persisted charge
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
61a5e64 to
33612da
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
openmeter/billing/charges/creditpurchase/service/create.go (1)
24-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winSame custom-currency gate copy-pasted three times. Since this PR is unifying the gate across flat-fee, usage-based, and credit-purchase creation anyway, it's a great moment to pull the shared
IsCustom() && !enabledcheck + error wrap into one small helper (e.g. in themetapackage) instead of hand-copying it.
openmeter/billing/charges/creditpurchase/service/create.go#L24-L24: replace the inline guard with a call to the shared helper, passing the credit-purchase-specific error message/action text.openmeter/billing/charges/flatfee/service/create.go#L35-L35: same swap for the flat-fee guard.openmeter/billing/charges/usagebased/service/create.go#L34-L34: same swap for the usage-based guard.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@openmeter/billing/charges/creditpurchase/service/create.go` at line 24, The custom-currency eligibility check and wrapped error are duplicated across the creation services; extract them into one shared helper, such as in the meta package, accepting the currency and operation-specific error/action text. Update openmeter/billing/charges/creditpurchase/service/create.go:24, openmeter/billing/charges/flatfee/service/create.go:35, and openmeter/billing/charges/usagebased/service/create.go:34 to call that helper with their respective messages, preserving the existing gate behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@openmeter/billing/charges/creditpurchase/service/create.go`:
- Line 24: The custom-currency eligibility check and wrapped error are
duplicated across the creation services; extract them into one shared helper,
such as in the meta package, accepting the currency and operation-specific
error/action text. Update
openmeter/billing/charges/creditpurchase/service/create.go:24,
openmeter/billing/charges/flatfee/service/create.go:35, and
openmeter/billing/charges/usagebased/service/create.go:34 to call that helper
with their respective messages, preserving the existing gate behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 17f249f2-cf0b-4659-9ec4-347b266d717d
📒 Files selected for processing (22)
.agents/skills/charges/SKILL.mdopenmeter/billing/charges/creditpurchase/charge.goopenmeter/billing/charges/creditpurchase/service/create.goopenmeter/billing/charges/creditpurchase/service/external_test.goopenmeter/billing/charges/creditpurchase/service/service.goopenmeter/billing/charges/creditpurchase/settlement.goopenmeter/billing/charges/creditpurchase/settlement_test.goopenmeter/billing/charges/flatfee/service/create.goopenmeter/billing/charges/service/creditpurchase_test.goopenmeter/billing/charges/service/flatfee_costbasis_test.goopenmeter/billing/charges/service/invoicable_test.goopenmeter/billing/charges/service/taxcode_test.goopenmeter/billing/charges/service/usagebased_costbasis_test.goopenmeter/billing/charges/usagebased/service/create.goopenmeter/billing/creditgrant/service/service.goopenmeter/ledger/chargeadapter/creditpurchase_test.goopenmeter/ledger/customerbalance/service_test.goopenmeter/ledger/customerbalance/testenv_test.gotest/app/stripe/invoice_credits_test.gotest/credits/credit_then_invoice_test.gotest/credits/sanity_lifecycle_test.gotest/credits/sanity_test.go
33612da to
ba556a2
Compare
What this unlocks
Custom-currency credit purchases can now move through the charges and billing flow while settling in fiat. The purchase keeps its credit currency and amount, while the generated invoice line carries the converted fiat total needed by billing.
This establishes the charges-side contract needed for the ledger integration to follow: custom-currency purchases remain disabled by default and return the usual unsupported error until downstream support is enabled explicitly.
It also makes the custom-currency gate consistent across flat-fee, usage-based, and credit-purchase charge creation, so rollout can happen without allowing unsupported charge shapes through another settlement mode.
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Greptile Summary
Custom-currency credit purchases can now retain their purchased currency while settling invoice and external payments in fiat.
Confidence Score: 5/5
The PR appears safe to merge because no eligible blocking failures remain.
No blocking failure remains.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart LR Purchase[Custom-currency credit purchase] --> Gate{Custom currency enabled?} Gate -->|No| Unsupported[Return unsupported error] Gate -->|Yes| Charge[Create charge in purchased currency] Charge --> Conversion[Multiply credit amount by cost basis] Conversion --> FiatLine[Create gathering line in settlement fiat] FiatLine --> Invoice[Billing invoice flow]Reviews (4): Last reviewed commit: "feat(customcurrencies): support credit p..." | Re-trigger Greptile
Context used: